'use strict';

let {vec2,vec3} = require('gl-matrix');

let tmpVec3_1 = vec3.create();
let tmpVec3_2 = vec3.create();
const NO_VALUE = -1;

class IdxGroup {
    constructor(){
        this.idxPos = NO_VALUE;
        this.idxTexCoord = NO_VALUE;
        this.idxNormal = NO_VALUE;
    }
}

class ObjFace {
    constructor(v1, v2, v3) {
        this.idxGroups = [new IdxGroup(), new IdxGroup(), new IdxGroup()];
        this.parseLine(v1, this.idxGroups[0]);
        this.parseLine(v2, this.idxGroups[1]);
        this.parseLine(v3, this.idxGroups[2]);
    }

    parseLine(v, idxGroup) {
        const tokens = v.split('/');
        const len = tokens.length;
        idxGroup.idxPos = parseInt(tokens[0]) - 1;
        if (len > 1) {
            const texCoord = tokens[1];
            idxGroup.idxTexCoord = texCoord.length > 0 ? parseInt(texCoord) - 1 : IdxGroup.NO_VALUE;
            if (len > 2) {
                idxGroup.idxNormal = tokens[2].length > 0 ? parseInt(tokens[2]) - 1 : IdxGroup.NO_VALUE;
            }
        }
    }
}


function reorderList(vertices, texCoords, normals, faces) {
    let indicesArray = [];
    let posArray = [];
    for (let i = 0, ilen = vertices.length; i < ilen; ++i) {
        posArray.push(vertices[i][0], vertices[i][1], vertices[i][2]);
    }
    let texCoordArray = new Array(vertices.length * 2);
    let normalArray = new Array(vertices.length * 3);
    for (let i = 0, ilen = faces.length; i < ilen; ++i) {
        let idxGroups = faces[i].idxGroups;
        processFaceVertex(idxGroups[0], texCoords, texCoordArray, normals, normalArray, indicesArray);
        processFaceVertex(idxGroups[1], texCoords, texCoordArray, normals, normalArray, indicesArray);
        processFaceVertex(idxGroups[2], texCoords, texCoordArray, normals, normalArray, indicesArray);

        // 如果没用法线数据,手动计算面法线
        if (
            idxGroups[0].idxNormal < 0 ||
            idxGroups[1].idxNormal < 0 ||
            idxGroups[2].idxNormal < 0
        ) {
            let v0 = vertices[idxGroups[0].idxPos];
            let v1 = vertices[idxGroups[1].idxPos];
            let v2 = vertices[idxGroups[2].idxPos];
            let v01 = vec3.sub(tmpVec3_1, v1, v0);
            let v12 = vec3.sub(tmpVec3_2, v2, v1);
            vec3.cross(tmpVec3_1, v01, v12);
            vec3.normalize(tmpVec3_1, tmpVec3_1);
            normalArray[3 * idxGroups[0].idxPos] = tmpVec3_1[0];
            normalArray[3 * idxGroups[0].idxPos + 1] = tmpVec3_1[1];
            normalArray[3 * idxGroups[0].idxPos + 2] = tmpVec3_1[2];

            normalArray[3 * idxGroups[1].idxPos] = tmpVec3_1[0];
            normalArray[3 * idxGroups[1].idxPos + 1] = tmpVec3_1[1];
            normalArray[3 * idxGroups[1].idxPos + 2] = tmpVec3_1[2];

            normalArray[3 * idxGroups[2].idxPos] = tmpVec3_1[0];
            normalArray[3 * idxGroups[2].idxPos + 1] = tmpVec3_1[1];
            normalArray[3 * idxGroups[2].idxPos + 2] = tmpVec3_1[2];
        }
    }
    // console.log("vertices:",posArray);
    // console.log("normals:",normalArray);
    // console.log("texCoords:",texCoordArray);

    // 检查normals


    return {
        positions: posArray,
        normals: normalArray,
        texCoords: texCoordArray,
        indices: indicesArray,
    };
}

function processFaceVertex(idxGroup, texCoords, texCoordArray, normals, normalArray, indicesArray) {
    let posIndex = idxGroup.idxPos;
    indicesArray.push(posIndex);

    // 如果有纹理
    if (idxGroup.idxTexCoord >= 0) {
        texCoordArray[2 * posIndex] = texCoords[idxGroup.idxTexCoord][0];
        texCoordArray[2 * posIndex + 1] = 1 - texCoords[idxGroup.idxTexCoord][1];  // 翻转Y坐标
    } else {
        texCoordArray[2 * posIndex] = 0;
        texCoordArray[2 * posIndex + 1] = 0;
    }

    if (idxGroup.idxNormal >= 0) {
        normalArray[3 * posIndex] = normals[idxGroup.idxNormal][0];
        normalArray[3 * posIndex + 1] = normals[idxGroup.idxNormal][1];
        normalArray[3 * posIndex + 2] = normals[idxGroup.idxNormal][2];
    }
}

function parse(objdata) {
    let lines = objdata.split('\n');

    let vertices = [];
    let texCoords = [];
    let normals = [];
    let faces = [];

    for (let i = 0, ilen = lines.length; i < ilen; ++i) {
        let tokens = lines[i].split(/\s+/g);
        switch (tokens[0]) {
            case 'v':
                vertices.push(vec3.fromValues(
                    parseFloat(tokens[1]),
                    parseFloat(tokens[2]),
                    parseFloat(tokens[3])
                ));
                break;
            case 'vt':
                texCoords.push(vec2.fromValues(
                    parseFloat(tokens[1]),
                    parseFloat(tokens[2])
                ));
                break;
            case 'vn':
                normals.push(vec3.fromValues(
                    parseFloat(tokens[1]),
                    parseFloat(tokens[2]),
                    parseFloat(tokens[3])
                ));
                break;
            case 'f':
                faces.push(new ObjFace(tokens[1], tokens[2], tokens[3]));
                break;
            default:
                // ignore
                break;
        }
    }

    return reorderList(vertices, texCoords, normals, faces);
}
module.exports = {
    parse:parse
};





